#include "./../../../include/online/RecommendWords/Dictionary.h"
#include "./../../../include/online/Tools/Configuration.h"
#include "./../../../include/online/Tools/MyLogger.h"

#include <fstream>
#include <sstream>

using std::ifstream;
using std::istringstream;
using std::ostringstream;

Dictionary *Dictionary::_pInstance = nullptr;
pthread_once_t Dictionary::_once = PTHREAD_ONCE_INIT;

Dictionary *Dictionary::getInstance()
{
    pthread_once(&_once, init_r);
    return _pInstance;
}

// 通过词典文件路径初始化词典和索引
void Dictionary::init()
{
    LogInfo("Initializing Dictionary...");
    getEnDict();
    getCnDict();
    getEnIndexTable();
    getCnIndexTable();
    LogInfo("Dictionary initialization complete.");
}

// 获取英文词典
vector<pair<string, int>> &Dictionary::getEnDict()
{
    string filename = Configuration::getInstance()->getMapValue("eg_dict.dat");
    ifstream ifs(filename);
    if (!ifs)
    {
        LogError("Unable to open file: " + filename);
        static vector<pair<string, int>> vecEnDict;
        return vecEnDict;
    }

    string line;
    while (getline(ifs, line))
    {
        string word;
        int frequency;
        istringstream iss(line);
        iss >> word >> frequency;
        _EnDict.push_back(pair<string, int>(word, frequency));
    }
    ifs.close();
    return _EnDict;
}

// 获取中文词典
vector<pair<string, int>> &Dictionary::getCnDict()
{
    string filename = Configuration::getInstance()->getMapValue("cn_dict.dat");
    ifstream ifs(filename);
    if (!ifs)
    {
        LogError("Unable to open file: " + filename);
        static vector<pair<string, int>> vecCnDict;
        return vecCnDict;
    }

    string line;
    while (getline(ifs, line))
    {
        string word;
        int frequency;
        istringstream iss(line);
        iss >> word >> frequency;
        _CnDict.push_back(pair<string, int>(word, frequency));
    }
    ifs.close();
    return _CnDict;
}

// 获取英文索引表
unordered_map<string, unordered_set<int>> &Dictionary::getEnIndexTable()
{
    string filename = Configuration::getInstance()->getMapValue("eg_dictIndex.dat");
    ifstream ifs(filename);
    if (!ifs)
    {
        LogError("Unable to open file: " + filename);
        static unordered_map<string, unordered_set<int>> mapEnIndex;
        return mapEnIndex;
    }

    string line;
    while (getline(ifs, line))
    {
        string word;
        int index;
        istringstream iss(line);
        iss >> word;
        while (iss >> index)
        {
            _EnIndexTable[word].insert(index);
        }
    }
    ifs.close();
    return _EnIndexTable;
}

// 获取中文索引表
unordered_map<string, unordered_set<int>> &Dictionary::getCnIndexTable()
{
    string filename = Configuration::getInstance()->getMapValue("cn_dictIndex.dat");
    ifstream ifs(filename);
    if (!ifs)
    {
        LogError("Unable to open file: " + filename);
        static unordered_map<string, unordered_set<int>> mapCnIndex;
        return mapCnIndex;
    }

    string line;
    while (getline(ifs, line))
    {
        string word;
        int index;
        istringstream iss(line);
        iss >> word;
        while (iss >> index)
        {
            _CnIndexTable[word].insert(index);
        }
    }
    ifs.close();
    return _CnIndexTable;
}

// 构造函数
Dictionary::Dictionary()
{
    init();
}

// 析构函数
Dictionary::~Dictionary()
{
}

// 单例初始化
void Dictionary::init_r()
{
    if (_pInstance == nullptr)
    {
        _pInstance = new Dictionary();
        atexit(destory);
    }
}

// 单例销毁
void Dictionary::destory()
{
    if (_pInstance)
    {
        delete _pInstance;
        _pInstance = nullptr;
    }
}
